﻿using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Gezel.Model;
using Weazel.Gezel.Parser;
using Weazel.Gezel.Model.Errors;

namespace Weazel.Gezel.Simulator.Reference.Setup
{
	class IpBlockSetup
	{
		internal static void setupIpBlocks(Simulation sim, Weazel.Gezel.Model.Model model)
		{
			foreach (Weazel.Gezel.Model.IPBlock ipBlock in model.IPBlocks.Values)
			{
				// simply skip ipblocks which are not part
				// of the simulation
				if (!ipBlock.InSystem)
					continue;

				setupIpBlock(sim, ipBlock, model);
			}
		}

		internal static void setupIpBlock(
			Simulation sim,
			Weazel.Gezel.Model.IPBlock ipBlock,
			Weazel.Gezel.Model.Model model
		)
		{			
			AbstractIpBlock aip = sim.IpBlocks[ipBlock.Id] = IpBlockFactory.Create(ipBlock, sim);

			foreach (InPort inport in ipBlock.InPorts.Values)
			{
				Symid inportId = inport.Id;

				InputSignal i = new InputSignal(inportId, inport.Width, inport.Signed ? 1 : 0, inport.Name); // todo: refactor
				sim.signals[inportId] = i;
				aip.addInput(i, inport.LocalName, (uint)inport.Width, (uint)(inport.Signed ? 1 : 0));
			}

			foreach (OutPort outport in ipBlock.OutPorts.Values)
			{
				Symid outportId = outport.Id;

				IpOutputSignal o = new IpOutputSignal(outportId, (uint)outport.Width, outport.Signed, aip, sim);
				sim.signals[outportId] = o;
				aip.addOutput(o, outport.LocalName);
			}

			foreach (string param in ipBlock.IpParameters)
			{
				aip.SetParameter(param);
			}

			sim.IpBlocks[ipBlock.Id] = aip;
		}
	}
}
